#include "ZenMesh.h"

#define ZENVERTEX_TYPE (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1 )	

CZenMesh::CZenMesh()
{
	m_pMesh		= 0;
	m_NumMats	= 0;
	m_pTextures	= 0;
	m_pMaterials= 0;	
}

CZenMesh::~CZenMesh()
{
	if( m_pMesh )
		m_pMesh->Release();
	
//(delete[] m_pTextures;) niet afdoende, niet alleen C++ alloc maar ook DirectX Interfaces!!!!
	for (int i = 0; i < m_NumMats; i++)
		if (m_pTextures[i])
		{
			m_pTextures[i]->Release();
			m_pTextures[i] = NULL;
		}

	if( m_pTextures )
		delete[] m_pTextures;
//////////////////////////////////////////////////////////////////////////

	if( m_pMaterials )
		delete[] m_pMaterials;
}

HRESULT CZenMesh::LoadXFile(char * pstrPathName)
{
	HRESULT			res = 0;
	LPD3DXBUFFER	pMaterialBuffer = 0;

	res = ::D3DXLoadMeshFromX(pstrPathName, D3DXMESH_MANAGED, zen.m_pDevice, 0,
							 &pMaterialBuffer, (DWORD*)&m_NumMats, &m_pMesh);
	if (FAILED(res))
	{
		zen.SetError("Kan geen X-bestand laden met naam: ");
		zen.SetError(pstrPathName);
		return E_FAIL;
	}

	m_pTextures  = new LPDIRECT3DTEXTURE8[m_NumMats];
	m_pMaterials = new CZenMaterial[m_NumMats];

	D3DXMATERIAL * pMaterials = (D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();

	for ( int i = 0; i < m_NumMats; i++)
	{
		m_pMaterials[i].SetMaterial(pMaterials[i].MatD3D);
		m_pMaterials[i].SetAmbient(pMaterials[i].MatD3D.Diffuse.r,
								   pMaterials[i].MatD3D.Diffuse.g,
								   pMaterials[i].MatD3D.Diffuse.b);

		if (!pMaterials[i].pTextureFilename)
		{
			res = D3DXCreateTextureFromFile(zen.m_pDevice, "res/DefaultTexture.bmp", &m_pTextures[i]);
			if (FAILED(res))
			{
				zen.SetError("Kan geen default textuur laden voor mesh.");
			}
			continue;
		}
		
		char * resource = new char[strlen("res/") + strlen(pMaterials[i].pTextureFilename) + 1]; 

		if (resource != NULL) 
		{
			strcpy(resource, "res/");
			strcat(resource, pMaterials[i].pTextureFilename);
		}

		res = ::D3DXCreateTextureFromFile(zen.m_pDevice, resource, &m_pTextures[i]);
		if (FAILED(res))
		{
			zen.SetError("Kan geen textuur laden voor mesh met bestandsnaam:");
			zen.SetError(pMaterials[i].pTextureFilename);
			res = D3DXCreateTextureFromFile(zen.m_pDevice, "res/DefaultTexture.bmp", &m_pTextures[i]);
			if (FAILED(res))
			{
				zen.SetError("Kan geen default textuur laden voor mesh.");
			}
		} 

		delete resource;
	}

	pMaterialBuffer->Release();
	pMaterialBuffer = NULL;

	return S_OK;	
}

HRESULT CZenMesh::Render()
{
	HRESULT res = E_FAIL;

	for ( int i = 0; i < m_NumMats; i++)
	{
		m_pMaterials[i].Update();
		zen.m_pDevice->SetTexture(0, m_pTextures[i]);
		res = m_pMesh->DrawSubset(i);
	}

	zen.m_pDevice->SetVertexShader(ZENVERTEX_TYPE);

	return res;
}

int CZenMesh::GetSize()
{
	return sizeof( *this );
}

void CZenMesh::ClearTexture()
{
	for ( int i = 0; i < m_NumMats; i++)
	{
			m_pTextures[i]->Release();
			m_pTextures[i] = NULL;
	}
}

void CZenMesh::SetMaterial( CZenMaterial* pMaterial )
{
	for( int i = 0 ; i < m_NumMats ; i++ )
	{
		CopyMemory( &m_pMaterials[i].m_Material, &pMaterial->m_Material, sizeof( D3DMATERIAL8 ) );
	}
}
